import PELineElement from 'element/components/line'
import PETextElement from 'element/components/text'
import { moObserve } from 'element/share/observer'
import PEAreaElement from '..'

export interface Temp {
  composition: boolean
}

export function bind(el: PEAreaElement) {
  const temp: Temp = {
    composition: false,
  }

  const area = el.query('[contenteditable="true"]') as HTMLDivElement
  bindChange(area, temp)
}

/**
 * 绑定输入监听
 * @param el
 * @param temp
 */
function bindInput(el: HTMLDivElement, temp: Temp) {
  el.addEventListener('compositionstart', function (e) {
    temp.composition = true
  })
  el.addEventListener('compositionend', function (e) {
    temp.composition = false
  })
}

interface AdjustItem {
  target: HTMLElement
  type: 'text' | 'child' | 'attr'
  before?: Node
  after?: Node
}

/**
 * 绑定 change 监听
 * @param el
 * @param temp
 */
function bindChange(area: HTMLDivElement, temp: Temp) {
  const option: MutationObserverInit = {
    characterData: true,
    childList: true,
    attributes: true,
  }

  const changeTemp: Set<Node> = new Set()
  const needAdjust: Map<HTMLElement, AdjustItem> = new Map()

  function attrCallback(target: HTMLElement, attr: string) {}

  function charCallback(mutation: MutationRecord) {
    const target = mutation.target as Text
    changeTemp.add(target)
    // const parent = target.parentNode
    // if (parent instanceof HTMLElement) {
    //   if (parent.nodeName === PETextElement.nodeName) {
    //     const data: AdjustItem = { target: parent, type: 'text' }
    //     needAdjust.set(parent, data)
    //   } else if (parent.nodeName === PELineElement.nodeName || parent === area) {
    //     const data: AdjustItem = { target: parent, type: 'text' }
    //     const before = target.previousSibling
    //     if (before) {
    //       data.before = before
    //     }
    //     needAdjust.set(parent, data)
    //   }
    // }
  }

  function nodeCallback(mutation: MutationRecord) {}

  function callback(mutations: MutationRecord[]) {
    mutations.forEach((mutation) => {
      switch (mutation.type) {
        case 'attributes':
          attrCallback(mutation.target as HTMLElement, mutation.attributeName as string)
          break
        case 'childList':
          nodeCallback(mutation)
          break
        case 'characterData':
          charCallback(mutation)
          break
      }
    })
  }

  moObserve(area, callback, option)
}
